/*
 * @Descripttion : 观察者模式（又名订阅者模式）
 * @Author       : QianFox Team
 * @Date         : 2022-04-18 13:21:55
 * @LastEditors  : QianFox Team
 * @LastEditTime : 2024-08-08 15:14:19
 */

import { _typeOf } from './utils';
import { scrollspy } from '../scrollspy';

function Observer() {
    // 内部订阅
    this._customers = {};
    // 外部订阅
    this.customers = {};
}

Observer.prototype._init = function () {
    this._domMutation();
};

/**
 * @description: 为订阅对象订阅消息类型
 * @param {*} customer     观察行为
 * @param {*} fn           观察行业发生之后，回调函数
 * @param {*} subid        观察 ID
 * @param {*} fnName       回调函数名称
 * @return {*}
 * @Date: 2022-04-18 13:59:48
 */
Observer.prototype._subscribe = function (customer, fn, subid, fnName) {
    if (customer === 'custom') {
        if (!this.customers[subid]) this.customers[subid] = {};
        this.customers[subid][fnName] = fn;
    } else {
        // 观察对象是否存在，不存在则创建一个数据
        if (!this._customers[customer]) {
            this._customers[customer] = [];
        }
        // 观察者是否存在，不存在添加，存在则替换
        let index = this._customers[customer].indexOf(fn);
        if (index === -1) {
            this._customers[customer].push(fn);
        } else {
            this._customers[customer][index] = fn;
        }
    }
};

/**
 * @description: 为订阅对象取消消息订阅
 * @param {*} customer     观察行为
 * @param {*} fn           观察行业发生之后，回调函数
 * @param {*} subid        观察 ID
 * @param {*} fnName       回调函数名称
 * @return {*}
 * @Date: 2022-04-18 14:35:48
 */
Observer.prototype._unsubscribe = function (customer, fn, subid, fnName) {
    if (customer === 'custom') {
        if (!this.customers[subid]) return;
        if (fnName) delete this.customers[subid][fnName];
    } else {
        if (!this._customers[customer]) return;
        if (!fn) {
            this._customers[customer] = null;
        } else {
            this._customers[customer] = this._customers[customer].filter(item => item !== fn);
        }
    }
};

/**
 * @description: 订阅消息发布接口
 * @param {*} customer
 * @param {*} subid        观察 ID
 * @param {*} fnName       回调函数名称
 * @param {*} success      成功后的回调函数 (确定后回调)
 * @param {*} fail         失败后的回调函数
 * @return {*}
 * @Date: 2022-04-18 14:35:40
 */
Observer.prototype._publiced = function (customer, data, subid, fnName, success, fail) {
    if (customer === 'custom') {
        if (this.customers[subid] && _typeOf(this.customers[subid][fnName]) === 'function') {
            this.customers[subid][fnName](data, success, fail);
        }
    } else {
        if (!this._customers[customer]) return;
        this._customers[customer].forEach(fun => {
            fun(data, success, fail);
        });
    }
};

/**
 * @description: 当DOM发生变化时
 * @return {*}
 * @Date: 2024-08-05 11:04:36
 */
Observer.prototype._domMutation = function () {
    // 创建一个新的MutationObserver实例
    const observer = new MutationObserver(() => {
        // 节点树发生了变化，在这里执行你的代码
        scrollspy.init();
    });

    // 配置观察器
    observer.observe(document.body, {
        childList: true,
        subtree: true,
    });
};

let observer = new Observer();

export { observer };
